package tsing.javase.javaweb.jwt.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author Tsing/吴清平
 * @Date 2022/10/11 14:38
 * @Version 1.0
 */
public class JWTUtils {

    /**
     * JWT 由 header 、payload 、sign 三部分组成
     *  header: Token类型  算法
     *      {
               "typ": "JWT",
               "alg": "HS256"
             }
        payload -有效负载（保存信息）：标准中注册的声明、公共的声明、私有的声明
             {
                 "sub": "1234567890",
                 "name": "John Doe",
                 "admin": true
             }

        Signature-签名：将header 、payload用base64编码后，通过.拼接，再通过Header中声明的算法进行加密 得到JWT的第三部分——签名

     * 生成tocken  header.payload.sign
     */
    private static final String SIGN = "qwer!@#";  //签名的秘钥：Secret

    public static String getToken(Map<String,String> map){

        Calendar instance = Calendar.getInstance();//日历的类
        instance.add(Calendar.DATE,7); //默认7天过期
        //创建jwt builder
        JWTCreator.Builder builder = JWT.create();

        //遍历map中的kv，生成payload
        map.forEach((k,v) -> {
            builder.withClaim(k,v);
        });

        String token = builder.withExpiresAt(instance.getTime())//指定令牌过期时间
                .sign(Algorithm.HMAC256(SIGN)); //sign

        return token;
    }

    /**
     * 验证token 合法性
     */

    public static boolean verify(String token){
        if(token==null){
            return false;
        }

        try {
            JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);

        } catch (JWTVerificationException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            return false;
        }
        return true;

    }

    /**
     * 获取token中信息的方法
     */

    public static DecodedJWT getTockenInfo(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        return verify;
    }


    public static void main(String[] args) {

        //获取token
        Map<String, String> map = new HashMap<>();
        map.put("uesrname","Tsing");
        map.put("password","666666");
        String token = JWTUtils.getToken(map);
        System.out.println(token);
        //验证token
        System.out.println(JWTUtils.verify(token));

        //获取token中的信息
        DecodedJWT tockenInfo = getTockenInfo(token);
        String header = tockenInfo.getHeader();

        System.out.println("header::"+header);


        //Base64解码
        String decode = new String(Base64.getDecoder().decode(header), StandardCharsets.UTF_8);
        System.out.println(decode);  //  {"typ":"JWT","alg":"HS256"}

        String payload = tockenInfo.getPayload();
        System.out.println("payload::" + payload);
        String dePayload = new String (Base64.getDecoder().decode(payload),StandardCharsets.UTF_8);
        System.out.println(dePayload);

        String signature = tockenInfo.getSignature();
        System.out.println("signature::" + signature);


    }

}
